package com.zheng.common.util;

import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang.StringUtils;

/**
 * 生成二维码工具类
 * @author lvb10
 *
 */
public class QRCodeUtil {

	private static final String CHARSET = "utf-8";
	public static final String FORMAT_NAME = "png";
	// 二维码尺寸
	private static final int QRCODE_SIZE = 600;
	// LOGO宽度
	private static final int WIDTH = 120;
	// LOGO高度
	private static final int HEIGHT = 120;
	private static final int QRCOLOR = 0xFF000000; // 默认是黑色
	private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色

	// 用于设置QR二维码参数
	private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {
		private static final long serialVersionUID = 1L;
		{
			put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 设置QR二维码的纠错级别（H为最高级别）具体级别信息
			put(EncodeHintType.CHARACTER_SET, CHARSET);// 设置编码方式
			put(EncodeHintType.MARGIN, 1);
		}
	};

	private static BufferedImage createImage(String content, String logoPath,
											 boolean needCompress) throws Exception {
		BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
				BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
		int width = bitMatrix.getWidth();
		int height = bitMatrix.getHeight();
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ?QRCOLOR
						: BGWHITE);
			}
		}
		if (logoPath == null || "".equals(logoPath)) {
			return image;
		}
		// 插入图片
		QRCodeUtil.insertImage(image, logoPath, needCompress);
		return image;
	}


	private static void insertImage(BufferedImage source, String logoPath,
									boolean needCompress) throws Exception {
		File file = new File(logoPath);
		if (!file.exists()) {
			System.err.println(""+logoPath+"   该文件不存在！");
			return;
		}
		Image src = ImageIO.read(new File(logoPath));
		int width = src.getWidth(null);
		int height = src.getHeight(null);
		if (needCompress) { // 压缩LOGO
			if (width > WIDTH) {
				width = WIDTH;
			}
			if (height > HEIGHT) {
				height = HEIGHT;
			}
			Image image = src.getScaledInstance(width, height,
					Image.SCALE_SMOOTH);
			BufferedImage tag = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.getGraphics();
			g.drawImage(image, 0, 0, null); // 绘制缩小后的图
			g.dispose();
			src = image;
		}
		// 插入LOGO
		Graphics2D graph = source.createGraphics();
		int x = (QRCODE_SIZE - width) / 2;
		int y = (QRCODE_SIZE - height) / 2;
		graph.drawImage(src, x, y, width, height, null);
		Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
		graph.setStroke(new BasicStroke(3f));
		graph.draw(shape);
		graph.dispose();
	}

	//获取生成二维码的图片流
	public static ByteArrayOutputStream encodeIO(String content,String logoPath,Boolean needCompress) throws Exception {
		BufferedImage image = QRCodeUtil.createImage(content, logoPath,
				needCompress);
		//创建储存图片二进制流的输出流
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		//将二进制数据写入ByteArrayOutputStream
		ImageIO.write(image, FORMAT_NAME, baos);
		return baos;
	}

	//测试
	public static void main(String[] args) throws Exception {
		String text = "ifarm";
		ByteArrayOutputStream encodeIO = QRCodeUtil.encodeIO(text, "C:\\tool\\bjs\\bjsserver\\zheng-umbrella\\zheng-umbrella-web\\src\\main\\resources\\logo.png", true);
		//输入数组
		System.out.println(Arrays.toString(encodeIO.toByteArray()));
	}
}